package com.itheima.project.web;

import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.itheima.project.basic.ResponseWrap;
import com.itheima.project.core.enums.file.FileEnum;
import com.itheima.project.face.FileFace;
import com.itheima.project.utils.ResponseWrapBuild;
import com.itheima.project.utils.SubjectContent;
import com.itheima.project.vo.file.FileVo;
import com.itheima.project.vo.file.UploadMultipartFile;
import com.itheima.project.vo.security.UserVo;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.io.IOUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.util.List;

/**
 * @ClassName FileController.java
 * @Description 附件controller
 */
@RestController
@RequestMapping("file")
@Api(tags = "附件controller")
@Slf4j
public class FileController {

    @Autowired
    FileFace fileFace;

    /***
     * @description 文件下载
     * @param fileId 上传对象
     * @return: com.itheima.travel.req.FileVo
     */
    @PostMapping(value = "down-load/{fileId}")
    @ApiOperation(value = "文件下载",notes = "文件下载")
    @ApiImplicitParams({
        @ApiImplicitParam(paramType = "path", name = "fileId",value = "附件Id",dataType = "Long")
    })
    public ResponseWrap<FileVo> downLoad(@PathVariable("fileId") Long fileId){
        FileVo fileVo = fileFace.downLoad(fileId);
        return ResponseWrapBuild.build(FileEnum.SUCCEED,fileVo);
    }

    /***
     * @description 文件上传-前端直接调用
     * @param file 上传对象
     * @return: com.itheima.travel.req.FileVo
     */
    @PostMapping(value = "up-load")
    @ApiOperation(value = "文件上传",notes = "文件上传")
    @ApiImplicitParams({
        @ApiImplicitParam(paramType = "form", name = "file", value = "文件对象", required = true, dataType = "__file")
    })
    public ResponseWrap<FileVo> upLoad(
            @RequestParam("file")MultipartFile file,
            FileVo fileVo) throws IOException {
        String subject = SubjectContent.getSubject();
        UserVo userVo = JSONObject.parseObject(subject,UserVo.class);
        fileVo.setEnterpriseId(userVo.getEnterpriseId());
        //构建文件上次对象
        UploadMultipartFile uploadMultipartFile = UploadMultipartFile
                .builder()
                .originalFilename(file.getOriginalFilename())
                .fileByte(IOUtils.toByteArray(file.getInputStream()))
                .build();
        //执行文件上传
        FileVo fileVoResult = fileFace.upLoad(uploadMultipartFile, fileVo);
        return ResponseWrapBuild.build(FileEnum.SUCCEED,fileVoResult);

    }

    /***
     * @description 文件上传-微服务远程调用
     * @param file 上传对象
     * @return: com.itheima.travel.req.FileVo
     */
    @PostMapping(value = "up-load/feign")
    @ApiOperation(value = "文件上传",notes = "文件上传")
    @ApiImplicitParams({
        @ApiImplicitParam(paramType = "form", name = "file", value = "文件对象", required = true, dataType = "UploadMultipartFile"),
        @ApiImplicitParam(paramType = "query", name = "businessType", value = "图片业务类型（参照数据字典BusinessType）", required = true, dataType = "String"),
        @ApiImplicitParam(paramType = "query", name = "businessId", value = "机构Id（操作人的所属机构Id）", required = true, dataType = "String")
    })
    public ResponseWrap<FileVo> upLoad(
            @RequestBody UploadMultipartFile file,
            @RequestParam("businessType") String  businessType,
            @RequestParam("enterpriseId") String  enterpriseId) throws IOException {
        FileVo fileVo = FileVo.builder()
                .businessType(businessType)
                .enterpriseId(new Long(enterpriseId))
                .build();
        //执行文件上传
        FileVo fileVoResult = fileFace.upLoad(file, fileVo);
        return ResponseWrapBuild.build(FileEnum.SUCCEED,fileVoResult);
    }

    /**
     * @Description 业务绑定单个附件
     * @param  fileVo 附件对象
     * @return
     */
    @PostMapping(value = "bind-business-id")
    @ApiOperation(value = "业务绑定文件",notes = "业务绑定文件")
    @ApiImplicitParam(name = "fileVo",value = "附件对象",required = true,dataType = "FileVo")
    public ResponseWrap<List<FileVo>> bindBusinessId(@RequestBody FileVo fileVo){
        log.info("绑定文件方法调用: {}",fileVo);
        List<FileVo> fileVos = fileFace.bindBusinessId(fileVo);
        return ResponseWrapBuild.build(FileEnum.SUCCEED,fileVos);
    }

    /**
     * @Description 业务绑定单个附件
     * @param  fileId 附件id
     * @param  businessId 业务id
     * @return
     */
    @PostMapping(value = "bind-business-id/{fileId}/{businessId}")
    @ApiOperation(value = "业务绑定文件",notes = "业务绑定文件")
    @ApiImplicitParams({
        @ApiImplicitParam(name = "fileId",value = "附件id",required = true,dataType = "Long"),
        @ApiImplicitParam(name = "businessId",value = "业务id",required = true,dataType = "Long")
    })
    public ResponseWrap<List<FileVo>> bindBusinessId(@PathVariable("fileId") Long fileId,
                                                     @PathVariable("businessId")  Long businessId){
        List<FileVo> fileVos = fileFace.bindBusinessId(FileVo.builder().id(fileId).businessId(businessId).build());
        return ResponseWrapBuild.build(FileEnum.SUCCEED,fileVos);
    }

    /**
     * @Description 移除业务原图片，并绑定新的图片到业务上
     * @param  fileVo 附件对象
     * @return
     */
    @PostMapping(value = "replace-bind-business-id")
    @ApiOperation(value = "移除业务原图片，并绑定新的图片到业务上",notes = "移除业务原图片，并绑定新的图片到业务上")
    @ApiImplicitParam(name = "fileVo",value = "附件对象",required = true,dataType = "FileVo")
    public ResponseWrap<Boolean> replaceBindBusinessId(@RequestBody FileVo fileVo){
        Boolean flag = fileFace.replaceBindBusinessId(fileVo);
        return ResponseWrapBuild.build(FileEnum.SUCCEED,flag);
    }

    /**
     * @Description 移除业务原图片，并批量绑定新的图片到业务上
     * @param  fileVos 附件对象
     * @return
     */
    @PostMapping(value = "replace-bind-batch-business-id")
    @ApiOperation(value = "移除业务原图片，并绑定新的图片到业务上",notes = "移除业务原图片，并绑定新的图片到业务上")
    @ApiImplicitParam(name = "fileVos",value = "附件对象",required = true,dataType = "FileVo")
    public ResponseWrap<Boolean> replaceBindBatchBusinessId(@RequestBody List<FileVo> fileVos){
        Boolean flag = fileFace.replaceBindBatchBusinessId(fileVos);
        return ResponseWrapBuild.build(FileEnum.SUCCEED,flag);
    }

    /**
     * @Description 相同业务绑定多个附件
     * @param  fileVos 相同业务的多个附件对象
     * @return
     */
    @PostMapping(value = "bind-batch-business-id")
    @ApiOperation(value = "业务绑定文件",notes = "业务绑定文件")
    @ApiImplicitParam(name = "fileVo",value = "附件对象",required = true,dataType = "FileVo")
    public ResponseWrap<List<FileVo>> bindBatchBusinessId(@RequestBody List<FileVo> fileVos){
        List<FileVo> fileVoResult = fileFace.bindBatchBusinessId(fileVos);
        return ResponseWrapBuild.build(FileEnum.SUCCEED,fileVoResult);
    }

    /**
     * @description 按业务ID查询附件
     * @param  fileVo 附件对象
     * @return java.util.List<com.itheima.travel.req.FileVo>
     */
    @PostMapping("/select-by-businessId")
    @ApiOperation(value = "查询业务对应附件",notes = "查询业务对应附件")
    @ApiImplicitParam(name = "fileVo",value = "附件对象",required = true,dataType = "FileVo")
    public ResponseWrap<List<FileVo>> findFileVoByBusinessId(@RequestBody FileVo fileVo)  {
        //查询所有有效状态的附件
        List<FileVo> fileVoList = fileFace.findFileVoByBusinessId(fileVo.getBusinessId());
        return ResponseWrapBuild.build(FileEnum.SUCCEED,fileVoList);
    }

    /**
     * @description 按业务ID查询附件
     * @param  businessId 附件对象Id
     * @return java.util.List<com.itheima.travel.req.FileVo>
     */
    @PostMapping("/select-by-businessId/{businessId}")
    @ApiOperation(value = "查询业务对应附件",notes = "查询业务对应附件")
    @ApiImplicitParam(name = "businessId",value = "业务id",required = true,dataType = "Long")
    public ResponseWrap<List<FileVo>> findFileVoByBusinessId(@PathVariable("businessId") Long businessId)  {
        //查询所有有效状态的附件
        List<FileVo> fileVoList = fileFace.findFileVoByBusinessId(businessId);
        return ResponseWrapBuild.build(FileEnum.SUCCEED,fileVoList);
    }

    /**
     * @Description 删除附件
     * @param fileVo 查询条件
     * @return
     */
    @DeleteMapping("/delete-by-fileId")
    @ApiOperation(value = "删除附件",notes = "删除附件")
    @ApiImplicitParam(name = "fileVo",value = "附件对象",required = true,dataType = "FileVo")
    public ResponseWrap<Boolean> deleteFile(@RequestBody FileVo fileVo) {
        //删除附件信息
        Boolean flag = fileFace.deleteFileVo(fileVo.getCheckedIds());
        return ResponseWrapBuild.build(FileEnum.SUCCEED,flag);
    }

    /**
     * @Description 删除业务相关附件
     * @param fileVo 附件信息
     * @return
     */
    @DeleteMapping("/delete-by-businessId")
    @ApiOperation(value = "删除业务对应附件",notes = "删除业务对应附件")
    @ApiImplicitParam(name = "fileVo",value = "附件对象",required = true,dataType = "FileVo")
    public ResponseWrap<Boolean> deleteFileVoByBusinessId(@RequestBody FileVo fileVo) {
        //删除业务对应的所有附件信息
        Boolean flag = fileFace.deleteFileVoByBusinessId(fileVo.getBusinessId());
        return ResponseWrapBuild.build(FileEnum.SUCCEED,flag);
    }

    /***
     * @description 附件列表
     *
     * @param fileVo 查询条件
     * @param pageNum 页码
     * @param pageSize 每页条数
     * @return: com.baomidou.mybatisplus.extension.plugins.pagination.Page<com.itheima.restkeeper.req.DataDictVo>
     */
    @PostMapping("page/{pageNum}/{pageSize}")
    @ApiOperation(value = "查询附件分页",notes = "查询附件分页")
    @ApiImplicitParams({
        @ApiImplicitParam(name = "fileVo",value = "附件查询对象",required = false,dataType = "FileVo"),
        @ApiImplicitParam(paramType = "path",name = "pageNum",value = "页码",example = "1",dataType = "Integer"),
        @ApiImplicitParam(paramType = "path",name = "pageSize",value = "每页条数",example = "10",dataType = "Integer")
    })
    public ResponseWrap<Page<FileVo>> findFileVoPage(
        @RequestBody FileVo fileVo,
        @PathVariable("pageNum") int pageNum,
        @PathVariable("pageSize") int pageSize) {
        //查询附件分页信息
        Page<FileVo> fileVoPage = fileFace.findFileVoPage(fileVo, pageNum, pageSize);
        return ResponseWrapBuild.build(FileEnum.SUCCEED,fileVoPage);
    }

}

